#if !defined(__MEMCACHEASIO_POOLCONNECTION___)
#define __MEMCACHEASIO_POOLCONNECTION___

/* Copyright (c) 2008, dZettaApart.
   Licensed under the BSD License.
   See COPYING for details. */

#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>

#include <cstdlib>
#include <deque>
#include <list>
#include <iostream>

#include "memcacheasio_request.h"
#include "memcacheasio_connection.h"

namespace memcacheasio
{

	class Memcacheasio_p;

	class ConnectionsPool : public boost::enable_shared_from_this<ConnectionsPool>, private boost::noncopyable
	{
			friend class Memcacheasio_p;
			friend class Connection;
		public:
			typedef boost::function2<void, Connection::Ptr, const boost::system::error_code&> cb_addConnection;

			ConnectionsPool ( boost::asio::io_service& /*io_service*/ );
			~ConnectionsPool();

			void init ( const std::string& /*host*/, const std::string& /*port*/, int /*count_connection*/, int /*tryCount*/, int /*tryTimeout*/, unsigned int /*limitConnection*/ );

			/// Stop the server.
			void stop();

			void getConnection ( cb_addConnection /*cb*/ );

			std::string host() { return _host; };
			std::string	port() { return _port; };

			boost::asio::io_service& io_service() { return _io_service; };

		private:
			void newConnection();
			void queueConnection ( const boost::system::error_code& /*err*/, Connection::Ptr /*connection*/ );
			void checkAvailableConnection ( const boost::system::error_code& /*err*/ );
			void timeoutNewConnection ( const boost::system::error_code& /*err*/ );

		private:
			boost::mutex 				_mutex;
			std::deque<Connection::Ptr> _available_connections;
			std::list<Connection::Ptr> 	_serve_connections;
			std::list<Connection::Ptr> 	_new_connections;
			std::string 				_host;
			std::string					_port;

			boost::asio::io_service&	_io_service;

			boost::asio::deadline_timer _try_timer;
			boost::asio::deadline_timer _try_timer_connect;
			unsigned int  				_limitConnection;
			int                 		_try_connect;
			int                 		_try_count;
			int                 		_timeout_request;
			int                 		_timeout_connect;
			bool						_stopped;
			int 						_countConnection;

			std::deque<cb_addConnection>		_request_queue;
	};

}; //namespace memcacheasio

#endif // !defined(__MEMCACHEASIO_POOLCONNECTION___)
